import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreatePageDto } from './dto/create-page.dto';
import { UpdatePageDto } from './dto/update-page.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Page, StatusContent } from './entities/page.entity';
import { QueryPageDto } from './dto/query-page-dto';

@Injectable()
export class PageService {
  constructor(
    @InjectRepository(Page)
    private pageRepository: Repository<Page>,
  ) {}
  async create(createPageDto: CreatePageDto) {
    const { path } = createPageDto;
    const exist = await this.pageRepository.findOne({ where: { path } });
    if (exist) {
      throw new HttpException('页面已存在', HttpStatus.BAD_REQUEST);
    }
    if (createPageDto.status === StatusContent.Publish) {
      createPageDto.publishTime = new Date();
    }
    const createPage = await this.pageRepository.create(createPageDto);
    await this.pageRepository.save(createPageDto);
    return createPage;
  }

  async findAll(query: QueryPageDto) {
    const { pageNum = 1, pageSize = 10, status, ...otherQuery } = query;

    const qb = await this.pageRepository
      .createQueryBuilder('page')
      .take(pageSize)
      .skip((pageNum - 1) * pageSize)
      .orderBy('page.order', 'DESC')
      .select([
        'page.id',
        'page.name',
        'page.path',
        'page.order',
        'page.isCommentOpen',
        'page.status',
        'page.views',
        'page.publishTime',
        'page.createTime',
        'page.updateTime',
      ]);
    if (status) {
      qb.andWhere('page.status = :status', { status });
    }
    if (otherQuery) {
      Object.keys(otherQuery).forEach((q) => {
        if (otherQuery[q])
          qb.andWhere(`page.${q} LIKE :${q}`, {
            [`${q}`]: `${otherQuery[q]}`,
          });
      });
    }
    return {
      count: await qb.getCount(),
      list: await qb.getMany(),
    };
  }
  async findAllPages() {
    const qb = await this.pageRepository
      .createQueryBuilder('page')
      .orderBy('page.order', 'DESC')
      .select([
        'page.id',
        'page.name',
        'page.path',
        'page.order',
        'page.isCommentOpen',
        'page.status',
        'page.views',
        'page.publishTime',
        'page.createTime',
        'page.updateTime',
      ]);
    return await qb.getMany();
  }
  async findOne(id: string) {
    return await this.pageRepository.findOne({ where: { id: id } });
  }

  async update(id: string, updatePageDto: UpdatePageDto) {
    const old = await this.pageRepository.findOne({ where: { id: id } });
    const { status } = updatePageDto;
    const updatedPage = await this.pageRepository.merge(old, {
      ...updatePageDto,
      publishTime:
        status === StatusContent.Publish ? new Date() : old.publishTime,
    });
    return this.pageRepository.save(updatedPage);
  }

  findViewsByPath(path: string): Promise<Page> {
    return this.pageRepository
      .createQueryBuilder()
      .where(' path = :path ', { path })
      .getOne();
  }

  async remove(id: string) {
    const page = await this.pageRepository.findOne({ where: { id: id } });
    return this.pageRepository.remove(page);
  }
}
